// 版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package ssa

// 转换为机器相关操作
func lower(f *Func) {
	// 重复重写，直到找不到更多的重写
	applyRewrite(f, f.Config.lowerBlock, f.Config.lowerValue, removeDeadValues)
}

// checkLower检查是否有未通电的操作码，如果找到，则会失败。
func checkLower(f *Func) {
	// 需要是一个单独的阶段，因为它必须在这两个阶段之后运行
	// 降低和随后的死代码消除（因为降低
	// 规则可能会留下死的通用操作）。
	for _, b := range f.Blocks {
		for _, v := range b.Values {
			if !opcodeTable[v.Op].generic {
				continue // 降低
			}
			switch v.Op {
			case OpSP, OpSB, OpInitMem, OpArg, OpArgIntReg, OpArgFloatReg, OpPhi, OpVarDef, OpVarKill, OpVarLive, OpKeepAlive, OpSelect0, OpSelect1, OpSelectN, OpConvert, OpInlMark:
				continue // 好的，不要再低了
			case OpMakeResult:
				if b.Controls[0] == v {
					continue
				}
			case OpGetG:
				if f.Config.hasGReg {
					// 有硬件g寄存器，regalloc负责
					continue // 好的，不要再低了
				}
			}
			s := "not lowered: " + v.String() + ", " + v.Op.String() + " " + v.Type.SimpleString()

			for _, a := range v.Args {
				s += " " + a.Type.SimpleString()
			}
			f.Fatalf("%s", s)
		}
	}
}
